
package xib.parserTools.data;

import java.util.ArrayList;
import xib.parserTools.interfaces.IPanelData;
import xib.parserTools.interfaces.ISpeechBubbleData;
import xib.utils.XibDataException;

/**
 * Implementation from the interface IPanelData, this implementation is
 * used to save the data from the source before to be processed by the core.
 * @author xavierds
 */
public final class PanelData implements IPanelData{

    /**
     * Field with the information about the image identifier.
     */
    private String imageIdentifier;

    /**
     * Field with the location from the X axis.
     */
    private int locationX;

    /**
     * Field with the location from the Y axis.
     */
    private int locationY;

    /**
     * Field with the relative order of the panel in the page.
     */
     private int order;

    /**
     * Field with the height of the picture.
     */
    private int height;

    /**
     * Field with the width of the picture.
     */
    private int width;

    /**
     * Field who indicates if the panel was validate.
     */
    private boolean validate;

    /**
     * Field with the availables languages of the PanelData.
     */
    private ArrayList<String> languages;

    /**
     * Fiel with the PanelType of the Panel.
     */
    private PanelType panelType;

    /**
     * Field with the list of ISpeechBubbleData.
     */
    private ArrayList<ArrayList<ISpeechBubbleData>> speechBubblesData;

    /**
     * Constructs a new PanelData. All the fields are initialized with
     * null values.
     */
    public PanelData(){
        panelType = PanelType.WithText;
        languages = new ArrayList<String>();
        speechBubblesData = new ArrayList<ArrayList<ISpeechBubbleData>>();
    }

    public String getImageIdentifier(){
        if(imageIdentifier == null)
            throwXibDataException(new IllegalStateException("The  " +
                    "imageIdentifier has not been initialized properly."));
        return imageIdentifier;
    }

    public int getLocationX() {
        return locationX;
    }

    public int getLocationY() {
        return locationY;
    }

    public int getHeight(){
        if(height <= 0)
            throwXibDataException(new IllegalStateException("The height " +
                    "has not been initialized properly."));
        return height;
    }

    public int getWidth(){
        if(width <= 0)
            throwXibDataException(new IllegalStateException("The width " +
                    "has not been initialized properly."));
        return width;
    }
    
    public int getOrder(){
        if(order < 1)
            throwXibDataException(new IllegalStateException("The order " +
                    "has not been initialized properly."));
        return order;
    }

    public PanelType getPanelType(){
        return panelType;
    }

    public ArrayList<String> getLanguages(){
        if(panelType.equals(PanelType.WithText) && languages.size() == 0)
             throwXibDataException(new IllegalStateException("The languages " +
                    "have not been initialized properly."));
        return languages;
    }

    public ArrayList<ISpeechBubbleData> getSpeechBubblesDataByLanguage(String language){
        if(language == null)
             throwXibDataException(new NullPointerException("The given language" +
                    " can not be null."));
        int size = speechBubblesData.size();
        for(int i=0; i < size; i++){
            if(languages.get(i).equals(language))
                return speechBubblesData.get(i);
        }
        if(panelType.equals(PanelType.WithText))
            throwXibDataException(new IllegalStateException("The given language" +
                    " doesn't have any speechBubbles associated."));
        return new ArrayList<ISpeechBubbleData>();
    }

    public void setImageIdentifier(String imageIdentifier) {
        validate = false;
        if(imageIdentifier == null)
            throwXibDataException(new NullPointerException("The " +
                    "imageIdentifier can't be null."));
        if(imageIdentifier.equals(""))
            throwXibDataException(new IllegalArgumentException("The " +
                    "imageIdentifier must be different from the empty string."));
        this.imageIdentifier = imageIdentifier;
    }

    public void setWidthAndHeight(int width, int height) {
        validate = false;
        if(height <= 0 || width <= 0)
            throwXibDataException(new IllegalArgumentException("The width " +
                    "and the height must be greater than 0."));
        this.height = height;
        this.width = width;
    }

    public void setOrder(int order) {
        validate = false;
        if(order < 1)
            throwXibDataException(new IllegalArgumentException("The order " +
                    "must be greater than 0"));
        this.order = order;
    }

    public void setPanelType(PanelType panelType){
        validate = false;
        if(panelType == null)
            throwXibDataException(new NullPointerException("The " +
                    "PanelType can't be null."));
        this.panelType = panelType;
    }

    public void setLocationXY(int x, int y) {
        validate = false;
        if(x < 0 || y < 0)
            throwXibDataException(new IllegalArgumentException("The x and the y " +
                    "locations can't be less than 0."));
        this.locationX = x;
        this.locationY = y;
    }

    public void setLanguage(String language, ArrayList<ISpeechBubbleData> list){
        validate = false;
        if(language == null || list == null)
            throwXibDataException(new NullPointerException("The given language" +
                    " or list is null."));
        if(languages.contains(language))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language is already defined."));
        if(language.equals(""))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language can not be the empty String"));
        languages.add(language);
        speechBubblesData.add(list);
    }

    public boolean validate()   {
        if(!validate){
            //The height, width or location can't be 0
            if(height == 0 || width == 0 || order == 0)
                throwXibDataException(new IllegalStateException("Some values" +
                        " of the panel weren't properly initialized."));

            if(imageIdentifier == null)
                throwXibDataException(new NullPointerException("imageIdentifier " +
                        "wasn't initialized properly."));
            if(panelType.equals(PanelType.WithText) && languages.size() == 0)
                throwXibDataException(new IllegalStateException("No " +
                        "SpeechBubbleData weren't defined properly."));

            validate = true;
        }
        return true;
    }

    /**
     * Throw a new XibDataException with the cause from the given.
     * @param cause
     */
    private void throwXibDataException(Throwable cause){
        throw new XibDataException("Error in the internal data of the source, " +
                "in the PanelData."
                , cause);
    }

}
